//*************************************************************************************************
//***************************** (C) 2001 - 2008, Group 6 Incorporated *****************************
//*************************************************************************************************
//**
//**		  Tabs:  This file looks best with tab stops set every 6 spaces.
//**
//*************************************************************************************************
//*************************************************************************************************
//**
//**          File:  LCDCommands.asm
//**       Project:  Vehicle Detector - EE 400/401 Capstone Design Project
//**       Created:  27 Jan 2008 by Jordan Daniels / Chris Story
//**
//**   Description:  This file contains commands for interfacing with the
//			   attached 4x40 LCD.
//**			   Using 4 bit interface. C7:C4 = DB7:DB4
//**			   Update:  C2 = E1, C1 = RS , C3 = E2
//**			   Currently available commands:
//**
//**			   LCDBoardInit
//**			   PulseEnable
//**			   WritePulse
//**			   WriteChar
//**			   WriteCommand
//**
//*************************************************************************************************
//*************************************************************************************************


//=============================================================================
// LCDBoardInit
// Input Params:	None
// Output Params:	None
//-----------------------------------------------------------------------------
// Description:	Initializes LCD for operation. Sends various commands in
//			their required order.
//=============================================================================

LCDBoardInit:

//=============================================================================
// Initialize GPIO pins C7-C0 as output pins
//This routine steps through the initialization code for the LCD screen,
//follows the steps outlined in the datasheet.  Delays necessary for minimum
//timing requirements of the LCD
//=============================================================================

	st	r6, sp, 0		//Sub routine housekeeping
	st	r0, sp, 1
	add	sp, sp, 2
	mov r0, 0xFF00
	outp r0, GPCcfg


	jsr 	r6, DelayLong	//Wait for the board to set up

	mov 	r0, 0x00	//Set RS and E to low
	outp 	r0, GPCout

	mov 	r0, 0b00110000	//First Part of data to be written
	outp 	r0, GPCout
	jsr	r6, PulseEnable

	jsr	r6, DelayLong	//Wait, then pulse Enable
	mov 	r0, 0b00110000
	outp 	r0, GPCout
	jsr	r6, PulseEnable


	jsr	r6, DelayLong	//Wait, then pulse Enable
	mov 	r0, 0b00110000
	outp 	r0, GPCout
	jsr	r6, PulseEnable


	mov 	r0, 0b00100000	//Function Set to 4 bit data interfacing
	outp	r0, GPCout
	jsr	r6, PulseEnable

	mov 	r0, 0b00100000
	outp	r0, GPCout
	jsr	r6, PulseEnable


	mov	r0, 0b10000000	//Set up 1 line, 5x7 dot matrix font
	outp	r0, GPCout

	jsr	r6, PulseEnable


	mov	r0, 0b00000000	//display off (set)
	outp	r0, GPCout

	jsr	r6, PulseEnable

	mov	r0, 0b10000000
	outp	r0, GPCout

	jsr	r6, PulseEnable


	mov	r0, 0b00000000	//Display Clear
	outp	r0, GPCout

	jsr	r6, PulseEnable

	mov	r0, 0b00010000
	outp	r0, GPCout
	jsr	r6, PulseEnable


	mov	r0, 0b00000000	//Display Control

	outp	r0, GPCout

	jsr	r6, PulseEnable

	mov	r0, 0b00010000
	outp	r0, GPCout
	jsr	r6, PulseEnable

	mov	r0, 0b00000000	//Entry Mode (Set)
	outp	r0, GPCout

	jsr	r6, PulseEnable

	mov	r0, 0b11110000
	outp	r0, GPCout
	jsr	r6, PulseEnable


	mov r2,0b00101100
	jsr r6,WriteCommand
	mov r2,0b00000001
	jsr r6,WriteCommand2
	mov r2,0b00000010
	jsr r6,WriteCommand2
	mov r2,0b00001100
	jsr r6,WriteCommand2


	mov r2,0b00001100
	jsr r6,WriteCommand

	sub	sp, sp, 2	//Return stack pointer to original conditions
	ld	r6, sp, 0	//Restore the return value
	ld	r0, sp, 1	//Restore r0 from stack pointer

	jsr	r6, r6

//=============================================================================
// PulseEnable
//Call this immediately after you put the data on the output pins
//Retains the value of r0 and then pulses the enable pin (C2)
// Input Params:	r0 - Data that was just output onto C output port
// Output Params:	None
//-----------------------------------------------------------------------------
// Description:	Puts C2 high, waits 5 instruction cycles, then puts it low.
//=============================================================================

PulseEnable:	//Pulse the enable pin

	st	r6, sp, 0	//Housekeeping
	add	sp, sp, 1

	//mov	r1,0b00000100 marcinchange
	bis	r0,r0,2
	outp 	r0, GPCout
	jsr	r6, Delay	//Delay to allow for data to be input
	bic	r0,r0,2
	outp	r0, GPCout
	jsr	r6, DelayLong	//delay to satisfy min. cycle length condition

	sub	sp, sp, 1
	ld	r6, sp, 0


	jsr	r6, r6


//=============================================================================
// PulseEnable2
//Call this immediately after you put the data on the output pins
//Retains the value of r0 and then pulses the enable 2 pin (C3)
//
//This is used to write to the 2nd line of the lcd
//
// Input Params:	r0 - Data that was just output onto C output port
// Output Params:	None
//-----------------------------------------------------------------------------
// Description:	Puts C3 high, waits 5 instruction cycles, then puts it low.
//=============================================================================
PulseEnable2:	//Pulse the enable pin

	st	r6, sp, 0	//Housekeeping
	add	sp, sp, 1


	bis	r0,r0,3
	outp 	r0, GPCout

	jsr	r6, Delay	//Delay to allow for data to be input
	bic	r0,r0,3

	outp	r0, GPCout
	jsr	r6, DelayLong	//delay to satisfy min. cycle length condition

	sub	sp, sp, 1
	ld	r6, sp, 0


	jsr	r6, r6
//=============================================================================
// Write Enable
//Call this immediately after you put the data to be written on the output pins
//Retains the value of r0 and then pulses the enable pin (c2) and the rs pin (c0)
//
// Input Params:	r0 - Data that was just output onto C output port
// Output Params:	none
// Retains the value of r0
//-----------------------------------------------------------------------------
// Description:	Puts C2/C0  high, waits 5 instruction cycles, then puts them low.
//=============================================================================

WritePulse:	//Pulse with the ability to write data to the lcd

	st	r6, sp, 0	//Housekeeping
	add	sp, sp, 1

	bis	r0,r0,2	//set c2,c1
	bis	r0,r0,1
	outp 	r0, GPCout

	jsr	r6, Delay	//Delay to allow for data to be input

	bic	r0,r0,2	//clear c2,c1
	bic	r0,r0,1

	outp	r0, GPCout
	jsr	r6, DelayLong	//delay to satisfy min. cycle length condition


	sub	sp, sp, 1
	ld	r6, sp, 0
//	ld	r6, sp, 0

	jsr	r6, r6

	//=============================================================================
// Write Enable 2
//Call this immediately after you put the data to be written on the output pins
//Retains the value of r0 and then pulses the enable2 pin (c3) and the rs pin (c1)
//
//Writes to the second 2 lines of the LCD
//
// Input Params:	r0 - Data that was just output onto C output port
// Output Params:	none
// Retains the value of r0
//-----------------------------------------------------------------------------
// Description:	Puts C2/C0  high, waits 5 instruction cycles, then puts them low.
//=============================================================================

WritePulse2:	//Pulse with the ability to write data to the lcd

	st	r6, sp, 0	//Housekeeping
	add	sp, sp, 1

	bis	r0,r0,3	//set c2,c1
	outp 	r0, GPCout
	bis	r0,r0,1
	outp 	r0, GPCout

	jsr	r6, Delay	//Delay to allow for data to be input

	bic	r0,r0,3	//set c2,c1
	outp 	r0, GPCout
	bic	r0,r0,1
	outp 	r0, GPCout

	outp	r0, GPCout
	jsr	r6, DelayLong	//delay to satisfy min. cycle length condition


	sub	sp, sp, 1
	ld	r6, sp, 0
//	ld	r6, sp, 0

	jsr	r6, r6

//=============================================================================
// WriteChar
// Input Params:	r2
// Output Params:	None
//-----------------------------------------------------------------------------
// Description:	Takes the 8 bit value stored in r2 and seperates it to two 4
//			bit values, stored in r3 and r4. Then sends them in the
//			correct order to the LCD with E1 (I0) and RS (I1) high.
//			Used to write characters. NOT commands.
//=============================================================================

WriteChar:

	st	r6, sp, 0	//Store the return value in the stack pointer
	st	r2, sp, 1	//Store r2 in the stack pointer
	st	r3, sp, 2	//Store r3 in the stack pointer
	add	sp, sp, 3	//Realign stack pointer


	mov 	r3, 0x0000
	mov	r3,r2

	and	r2,r2,0x00F0
	mov	r0,r2
	jsr	r6, WritePulse

	rol	r2,r3,4
	and	r2,r2,0x00F0
	mov	r0,r2
	jsr	r6, WritePulse

	sub	sp, sp, 3	//Return stack pointer to original conditions
	ld	r6, sp, 0	//Restore the return value
	ld	r2, sp, 1	//Restore r4 from stack pointer
	ld	r3, sp, 2	//Restore r3 from stack pointer

	jsr	r6, r6

//=============================================================================
// WriteCommand
// Input Params:	r2
// Output Params:	None
//-----------------------------------------------------------------------------
// Description:	Takes the 8 bit value stored in r2 and seperates it to two 4
//			bit values, stored in r3 and r4. Then sends them in the
//			correct order to the LCD with E1 (I0) high and RS (I1) low.
//			Used to send commands. NOT characters.
//=============================================================================

WriteCommand:

	st	r6, sp, 0	//Store the return value in the stack pointer
	st	r2, sp, 1	//Store r2 in the stack pointer
	st	r3, sp, 2	//Store r3 in the stack pointer
	add	sp, sp, 3	//Realign stack pointer

	mov 	r3, 0x0000
	mov	r3,r2

	and	r2,r2,0x00F0
	mov	r0,r2
	jsr	r6, PulseEnable

	rol	r2,r3,4
	and	r2,r2,0x00F0
	mov	r0,r2
	jsr	r6, PulseEnable

	sub	sp, sp, 3	//Return stack pointer to original conditions
	ld	r6, sp, 0	//Restore the return value
	ld	r2, sp, 1	//Restore r4 from stack pointer
	ld	r3, sp, 2	//Restore r3 from stack pointer


	jsr	r6, r6

//=============================================================================
// WriteChar2
// Input Params:	r2
// Output Params:	None
//-----------------------------------------------------------------------------
// Description:	Takes the 8 bit value stored in r2 and seperates it to two 4
//			bit values, stored in r3 and r4. Then sends them in the
//			correct order to the LCD and writes them on the 2nd line
//=============================================================================

WriteChar2:

	st	r6, sp, 0	//Store the return value in the stack pointer
	st	r2, sp, 1	//Store r2 in the stack pointer
	st	r3, sp, 2	//Store r3 in the stack pointer
	add	sp, sp, 3	//Realign stack pointer

	mov 	r3, 0x0000
	mov	r3,r2

	and	r2,r2,0x00F0
	mov	r0,r2
	jsr	r6, WritePulse2

	rol	r2,r3,4
	and	r2,r2,0x00F0
	mov	r0,r2
	jsr	r6, WritePulse2

	sub	sp, sp, 3	//Return stack pointer to original conditions
	ld	r6, sp, 0	//Restore the return value
	ld	r2, sp, 1	//Restore r4 from stack pointer
	ld	r3, sp, 2	//Restore r3 from stack pointer


	jsr	r6, r6

//=============================================================================
// WriteCommand
// Input Params:	r2
// Output Params:	None
//-----------------------------------------------------------------------------
// Description:	Takes the 8 bit value stored in r2 and seperates it to two 4
//			bit values, stored in r3 and r4. Then sends them in the
//			correct order to the LCD with E1 (I0) high and RS (I1) low.
//			Used to send commands. NOT characters.
//=============================================================================

WriteCommand2:

	st	r6, sp, 0	//Store the return value in the stack pointer
	st	r2, sp, 1	//Store r2 in the stack pointer
	st	r3, sp, 2	//Store r3 in the stack pointer
	add	sp, sp, 3	//Realign stack pointer

	mov 	r3, 0x0000
	mov	r3,r2

	and	r2,r2,0x00F0
	mov	r0,r2
	jsr	r6, PulseEnable2

	rol	r2,r3,4
	and	r2,r2,0x00F0
	mov	r0,r2
	jsr	r6, PulseEnable2

	sub	sp, sp, 3	//Return stack pointer to original conditions
	ld	r6, sp, 0	//Restore the return value
	ld	r2, sp, 1	//Restore r4 from stack pointer
	ld	r3, sp, 2	//Restore r3 from stack pointer


	jsr	r6, r6


